//
// Created by ljy on 10/25/21.
//
#ifndef _LINUX_MMZONE_H
#define _LINUX_MMZONE_H
#include <asm-i386/atomic.h>
#include <linux/list.h>
#include <asm-i386/page.h>
#include <linux/spin_lock.h>

#define MAX_ORDER           10
#define MAX_NR_ZONES		3
#define ZONE_DMA		0
#define ZONE_NORMAL		1
#define ZONE_HIGHMEM		2
#define MAX_NR_ZONES		3
#define GFP_ZONEMASK	0x0f
#define MAX_NR_NODES		1

typedef struct free_area_struct {
    struct list_head	free_list;
    unsigned long		*map;
} free_area_t;

struct pglist_data;
/*
 * On machines where it is needed (eg PCs) we divide physical memory
 * into multiple physical zones. On a PC we have 3 zones:
 *
 * ZONE_DMA	  < 16 MB	ISA DMA capable memory
 * ZONE_NORMAL	16-896 MB	direct mapped by the kernel
 * ZONE_HIGHMEM	 > 896 MB	only page cache and user processes
 */
typedef struct zone_struct {
    spinlock_t		lock;
    unsigned long		free_pages;
    unsigned long		pages_min, pages_low, pages_high;
    int			need_balance;
    free_area_t		free_area[MAX_ORDER];

//    wait_queue_head_t	* wait_table;
//    unsigned long		wait_table_size;
//    unsigned long		wait_table_shift;
    struct pglist_data	*zone_pgdat;
    struct page		*zone_mem_map;
    unsigned long		zone_start_paddr;
    unsigned long		zone_start_mapnr;

    /*
     * rarely used fields:
     */
    char			*name;
    unsigned long		size;
} zone_t;

typedef struct zonelist_struct {
    zone_t * zones [MAX_NR_ZONES+1]; // NULL delimited
} zonelist_t;

typedef struct pglist_data {
    zone_t node_zones[MAX_NR_ZONES];
    zonelist_t node_zonelists[GFP_ZONEMASK+1];
    int nr_zones;
    struct page *node_mem_map;
    unsigned long *valid_addr_bitmap;
    struct bootmem_data *bdata;
    unsigned long node_start_paddr;
    unsigned long node_start_mapnr;
    unsigned long node_size;
    int node_id;
    struct pglist_data *node_next;
} pg_data_t;
extern pg_data_t *pgdat_list;
extern pg_data_t contig_page_data;
#define for_each_pgdat(pgdat) \
	for (pgdat = pgdat_list; pgdat; pgdat = pgdat->node_next)

#define MAP_ALIGN(x)	((((x) % sizeof(mem_map_t)) == 0) ? (x) : ((x) + \
		sizeof(mem_map_t) - ((x) % sizeof(mem_map_t))))
#endif
